﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;

namespace d39
{
    [Serializable]
    public class WallType
    {
        public WallType()
        {
            Color = Color.FromArgb(0, 0, 0);
            Segments = new List<Segment>();
            Thickness = 1;
            DashStyle = DashStyle.Solid;
            Opacity = 10;
        }

        [XmlIgnore]
        public Color Color { get; set; }

        [XmlAttribute("color")]
        public string ColorString
        {
            get { return ColorTranslator.ToHtml(Color); }
            set { Color = ColorTranslator.FromHtml(value); }
        }

        [XmlAttribute("opacity")]
        public int Opacity { get; set; }

        [XmlAttribute("thickness")]
        public int Thickness { get; set; }

        [XmlAttribute("name")]
        public string Description { get; set; }

        [XmlElement("wall")]
        public List<Segment> Segments { get; set; }

        [XmlAttribute("style")]
        public DashStyle DashStyle { get; set; }

        [XmlIgnore]
        public Color ColorWithOpacity
        {
            get { return Color.FromArgb((Opacity * 255) / 10, Color); }
        }

        [XmlIgnore]
        public string SegmentsString
        {
            get { return Segments.ToHumanReadableString(); }
            set { Segments = d39.Segments.ParseHumanReadableSegments(value); }
        }

        [XmlIgnore]
        public string CssStyle
        {
            get
            {
                var result = "color: " + ColorTranslator.ToHtml(Color) + "; border: " + Thickness + "px ";
                if (DashStyle == DashStyle.Dash)
                {
                    result += "dashed";
                }
                else if (DashStyle == DashStyle.Dot)
                {
                    result += "dotted";
                }
                else
                {
                    result += "solid";
                }
                return result + ColorTranslator.ToHtml(Color);
            }
        }

        // The format is:
        // O000000tdss.ss..-D
        // 000000 = Color
        // O = opacity, G through Q for 0% through 90% in units of 10%; omitted if 100%
        // t = thickness in pixels, 2-4, or 1 if omitted.
        // d = dashStyle: 8=dashed, 9=dotted, solid if omitted
        // ss.ss.. list of wall segments separated by . and terminated by ..
        // D = description, optional

        public static WallType FromString(string str)
        {
            var result = new WallType();
            int end = 0;
            if (str[end] >= 'G' && str[end] <= 'Q')
            {
                result.Opacity = (int)str[end++] - (int)'G';
            }
            result.Color = ColorTranslator.FromHtml('#' + str.Substring(end, 6));
            end += 6;
            if (end < str.Length && str[end] >= '2' && str[end] <= '4')
            {
                result.Thickness = int.Parse(str.Substring(end, 1));
                end++;
            }
            if (end < str.Length && (str[end] == '8' || str[end] == '9'))
            {
                result.DashStyle = (str[end] == '8' ? DashStyle.Dash : DashStyle.Dot);
                end++;
            }
            var descrStart = str.IndexOf('-', end);
            if (descrStart >= 0)
            {
                result.Description = str.Substring(descrStart + 1);
            }
            else
            {
                descrStart = str.Length;
            }
            result.Segments = d39.Segments.ParseSegments(str.Substring(end, descrStart - end));
            return result;
        }
        public string ToString(UrlTweaks tweaks)
        {
            bool includeDescription = tweaks.IncludeDescriptions;
            if (string.IsNullOrEmpty(Description)) includeDescription = false;
            var start = "";
            if (Opacity < 10) start += (char)((int)'G' + Opacity);
            start += ColorTranslator.ToHtml(Color).Substring(1);
            if (Thickness != 1) start += Thickness.ToString();
            if (DashStyle == DashStyle.Dash) start += '8';
            if (DashStyle == DashStyle.Dot) start += '9';
            start += Segments.ToSegmentString();
            return includeDescription ? start + "-" + Description : start;
        }
    }
}